<?php

namespace App\Listeners;

use App\BO\Order\OrderRollback\OrderRollbackProxy;
use App\BO\OrderStatus\Events\OrderCreateSuccessEvent;
use App\BO\OrderStatus\Events\OrderPayExpiredEvent;
use App\BO\OrderStatus\Events\OrderPaySuccessEvent;
use App\BO\OrderStatus\Events\OrderUserApplyRefundEvent;
use App\BO\OrderStatus\Events\OrderUserCancelEvent;
use App\BO\OrderStatus\Events\OrderUserCancelledRefundEvent;
use App\BO\OrderStatus\OrderStateDefinition;
use App\Entities\OrderCancelEntity;
use App\Entities\OrderEntity;
use App\Entities\OrderModel;
use App\Entities\OrderRefundEntity;
use App\Entities\OrderRefundModel;
use App\Jobs\ExpireOrder;
use App\ServicesNew\OrderService;
use App\Utils\RefundNoGeneratorUtil;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class OrderEventSubscriber
{
    public const  SUBSCRIBER = OrderEventSubscriber::class;

    /**
     * @return OrderService
     */
    private function getOrderService()
    {
        /** * @var OrderService $orderService */
        $orderService = app(OrderService::class);
        return $orderService;
    }

    /**
     * 订单创建成功时调用
     * @param OrderCreateSuccessEvent $event
     * @return void
     */
    public function onOrderCreateSuccess(OrderCreateSuccessEvent $event)
    {
        $order = $event->getOrder();

        // 设置过期监控 Job
        //ExpireOrder::dispatch($order->getId())->delay(config('app.order_ttl', '600'));
        Log::info('订单ID=' . $order->getId() . 'ExpireOrderJob 放入队列');
    }


    /**
     * @param OrderUserApplyRefundEvent $event
     */
    public function onOrderUserApplyRefund(OrderUserApplyRefundEvent $event)
    {
        $userApplyRefundInfo = $event->getUserApplyRefundInfo();

        // 增加记录
        OrderRefundEntity::addRecordFromOrder(
            $event->getOrder(),
            $userApplyRefundInfo->getReason(),
            '',
            OrderRefundModel::TYPE_USER_APPLY
        );

        $this->userApplyRefund($event->getOrder());
    }

    protected function userApplyRefund(OrderEntity $order)
    {
        DB::beginTransaction();

        // 1. 同步订单退款状态
        $orderRefundEntity = $this->getOrderService()->findOrderRefundOneByOrderId($order->getId());
        $orderRefundEntity->setRefundStatus($order->getOrderState());
        $orderRefundEntity->save();

        // 2. 给订单设置退款流水号
        $payments = $this->getOrderService()->getSupplementPaymentsByOrderId($order->getId());
        foreach ($payments as $payment) {
            $payment->setRefundTradeNo(RefundNoGeneratorUtil::get());
            $payment->save();
        }

        DB::commit();
    }

    /**
     * @param OrderUserCancelledRefundEvent $event
     */
    public function onOrderUserCancelledRefund(OrderUserCancelledRefundEvent $event)
    {
        $orderRefundEntity = OrderRefundEntity::findByOrderId($event->getOrder()->getId());
        $orderRefundEntity->setRefundStatus(OrderStateDefinition::STATE_REFUND_CANCELLED_BY_USER);
        $orderRefundEntity->save();
    }

    /**
     * @param OrderPaySuccessEvent $event
     */
    public function onOrderPaySuccess(OrderPaySuccessEvent $event)
    {
        $orderEntity = $event->getOrder();
        $payInfo = $event->getPayInfo();

        $orderEntity->setPaidAt($payInfo->getPaidAt());
        $orderEntity->setPaymentMethod($payInfo->getPaymentMethod());
        $orderEntity->setPaymentNo($payInfo->getPaymentNo());
        $orderEntity->setShipStatus(OrderModel::SHIP_STATUS_DISTRIBUTION);
        $orderEntity->save();
    }

    /**
     * 订单过期末支付
     * @param OrderPayExpiredEvent $event
     */
    public function onOrderPayExpired(OrderPayExpiredEvent $event)
    {
        OrderRollbackProxy::rollback($event->getOrder());
    }

    /**
     * 用户取消订单
     * @param OrderUserCancelEvent $event
     */
    public function onOrderUserCancel(OrderUserCancelEvent $event)
    {
        $orderEntity = $event->getOrder();
        $userCancelInfo = $event->getUserCancelInfo();

        OrderRollbackProxy::rollback($orderEntity);

        $orderCancelEntity = OrderCancelEntity::getNewInstance();
        $orderCancelEntity->setOrderId($orderEntity->getId());
        $orderCancelEntity->setUserId($orderEntity->getUserId());
        $orderCancelEntity->setReason($userCancelInfo->getReason());
        $orderCancelEntity->save();
    }

    /**
     * 为订阅者注册监听器。
     *
     * @param  \Illuminate\Events\Dispatcher  $events
     */
    public function subscribe($events)
    {
        $events->listen(
            OrderCreateSuccessEvent::class,
            self::SUBSCRIBER . '@onOrderCreateSuccess'
        );

        $events->listen(
            OrderUserCancelEvent::class,
            self::SUBSCRIBER . '@onOrderUserCancel'
        );

        $events->listen(
            OrderUserApplyRefundEvent::class,
            self::SUBSCRIBER . '@onOrderUserApplyRefund'
        );

        $events->listen(
            OrderUserCancelledRefundEvent::class,
            self::SUBSCRIBER . '@onOrderUserCancelledRefund'
        );

        $events->listen(
            OrderPaySuccessEvent::class,
            self::SUBSCRIBER . '@onOrderPaySuccess'
        );

        $events->listen(
            OrderPayExpiredEvent::class,
            self::SUBSCRIBER . '@onOrderPayExpired'
        );
    }
}
